package com.zdxlz.fcmp.common.core.util;

import cn.hutool.core.util.StrUtil;
import com.zdxlz.fcmp.common.core.exception.BizException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;

import java.io.File;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static com.zdxlz.fcmp.common.core.constant.CommonConstants.*;

/**
 * @description：公共工具类
 * @author：aman
 * @date：2025/3/7 10:18
 */
@Slf4j
public class CommUtils {

    /**
     * 生成UUID
     *
     * @return
     */
    public static String getUuid() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    // 根据 HttpServletRequest 获取 IP
    public static String getIpAddress(HttpServletRequest request) {
        if (request == null) {
            return "unknown";
        }
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if (LOCALHOST_IP.equalsIgnoreCase(ip) || LOCALHOST_IPV6.equalsIgnoreCase(ip)) {
                // 根据网卡取本机配置的 IP
                InetAddress iNet = null;
                try {
                    iNet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    log.error("出现异常：{}", e.getMessage(), e);
                }
                if (iNet != null)
                    ip = iNet.getHostAddress();
            }
        }
        // 对于通过多个代理的情况，分割出第一个 IP
        if (ip != null && ip.length() > 15) {
            if (ip.indexOf(SEPARATOR) > 0) {
                ip = ip.substring(0, ip.indexOf(SEPARATOR));
            }
        }
        return LOCALHOST_IPV6.equals(ip) ? LOCALHOST_IP : ip;
    }

    /**
     * 获取Object 固定key的value
     *
     * @param key    键值
     * @param object 对象
     * @return
     */
    public static Object getValueByKey(String key, Object object) {
        try {
            Field field = object.getClass().getDeclaredField(key);
            field.setAccessible(true); // 私有字段
            return field.get(object);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 转换object 为kv map
     *
     * @param object 对象
     * @return map
     */
    public static Map<String, Object> getObjectKVToMap(Object object) {
        Map<String, Object> keyValueMap = new HashMap<>();
        Class<?> clazz = object.getClass();
        while (clazz != null) {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                try {
                    field.setAccessible(true);
                    Object value = field.get(object);
                    keyValueMap.put(field.getName(), value);
                } catch (IllegalAccessException e) {
                    log.error("解析对象KV出现异常", e);
                    throw new BizException("解析参数对象KV出现异常");
                }
            }
            clazz = clazz.getSuperclass();
        }
        return keyValueMap;
    }

    /**
     * 替换字符串中的{}占位符
     *
     * @param value  字符串
     * @param fields 替换的值
     * @return 完整串
     */
    public static String replaceStrPlaceholder(String value, List<String> fields) {
        StringBuilder sb = new StringBuilder(value);
        int startIndex = sb.indexOf("{}");
        int fieldsIndex = 0;
        while (startIndex != -1 && fieldsIndex < fields.size()) {
            sb.replace(startIndex, startIndex + 2, fields.get(fieldsIndex));
            startIndex = sb.indexOf("{}", startIndex + fields.get(fieldsIndex).length());
            fieldsIndex++;
        }
        return sb.toString();
    }

    /**
     * 发送邮件
     *
     * @param module 邮件模块
     * @param value  邮件内容
     * @return 结果
     */
    public static int sendMail(String module, String value) {
        log.info("发送邮件，邮件主题：{}，邮件内容：{}", module, value);

        return 0;
    }

    /**
     * 完全基于ip2region.xdb文件，对用户ip地址进行转换
     * 注：并发调用时，每个线程需创建一个独立的searcher对象 单独使用。
     */
    public static String getIpPossessionByFile(String ip) {
        // ip2region.xdb 文件地址常量（本地xdb文件路径）
        File file = new File("ipdb/ip2region.xdb");
        if (StrUtil.isNotEmpty(ip)) {
            try {
                // 1、创建 searcher 对象
                Searcher searcher = Searcher.newWithFileOnly(file.getAbsolutePath());
                // 2、查询
                String region = searcher.search(ip);
                region = region.replace("|0", "");
                log.info("{地区: {}, IO操作数: {}}", region, searcher.getIOCount());
                return region;
            } catch (Exception e) {
                log.error("获取IP地址异常：{} ", e.getMessage());
                throw new RuntimeException("获取IP地址异常");
            }
        }
        return "未知";
    }

    public static void main(String[] args) {
        String ip = "114.88.125.4"; // 示例 IP 地址
        String location = getIpPossessionByFile(ip);
        System.out.println("Location: " + location);
    }
}
